package core

import (
	"encoding/json"
	"log"
	"net/http"
	"strings"
	"time"
)

func init() {
	http.HandleFunc("/", acceptAndProxy)   //转发请求
	http.HandleFunc("/ping", ping)         //心跳检测
	http.HandleFunc("/register", register) //服务注册
	http.HandleFunc("/admin/api", admin)   //面板数据接口
}

// prefixStr
//
//	@Description: 获取前缀
//	@param path
func prefixStr(path string) string {
	var splitpath = strings.Split(path, "/")
	return splitpath[1]
}

// acceptAndProxy
//
//	@Description: 转发请求
//	@param w
//	@param r
func acceptAndProxy(w http.ResponseWriter, r *http.Request) {
	if r.URL.Path == "/" {
		return
	}
	if r.URL.Path == "/favicon.ico" {
		return
	}
	prefix := prefixStr(r.URL.Path)
	send(prefix, w, r)
}

// ping
//
//	@Description: 心跳检测
//	@param w
//	@param r
func ping(w http.ResponseWriter, r *http.Request) {
	secret := r.Header.Get("secret")
	if secret != Secret {
		return
	}
	var instance = &server{}
	err := json.NewDecoder(r.Body).Decode(&instance)
	if err != nil {
		w.Write([]byte(err.Error()))
		return
	}
	timeUnix := time.Now().Unix()
	instance.nextHealthyTimes = timeUnix + (instance.HealthyTime * 2) //提高容错
	status := instance.CheckOrRegister()
	w.Write([]byte(status))
}

// register
//
//	@Description: 服务注册
//	@param w
//	@param r
func register(w http.ResponseWriter, r *http.Request) {
	secret := r.Header.Get("secret")
	if secret != Secret {
		return
	}
	var instance = &server{}
	err := json.NewDecoder(r.Body).Decode(&instance)
	if err != nil {
		w.Write([]byte(err.Error()))
		return
	}
	err = instance.register()
	if err != nil {
		w.Write([]byte(err.Error()))
	}
	timeUnix := time.Now().Unix()
	instance.nextHealthyTimes = timeUnix + instance.HealthyTime
	w.Write([]byte("success"))
	log.Println("register success:", instance.addr)
}

// admin
//
//	@Description: 面板数据接口
//	@param w
//	@param r
func admin(w http.ResponseWriter, r *http.Request) {
	secret := r.Header.Get("secret")
	if secret != Secret {
		return
	}
	keyName := r.URL.Query().Get("key")
	mp := make(map[string]any)
	service.Range(func(key, value any) bool {
		if keyName == "" || keyName == "a" {
			mp[key.(string)] = value.(*LoadBalance)
			return true
		}
		if keyName == key {
			mp[key.(string)] = value.(*LoadBalance)
			return true
		}
		return true
	})
	marshal, _ := json.Marshal(mp)
	w.Write(marshal)
}
